package com.ineatconseil.yougo.web.controllers;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.ineatconseil.yougo.bo.Request;
import com.ineatconseil.yougo.bo.User;
import com.ineatconseil.yougo.dao.RequestDao;
import com.ineatconseil.yougo.dao.UserDao;
import com.ineatconseil.yougo.dto.RequestDto;
import com.ineatconseil.yougo.web.exceptions.InternalServerErrorException;
import com.ineatconseil.yougo.web.exceptions.NotFoundException;

@Controller
@RequestMapping("/users/{userId}/requests")
public class RequestController {

	@Autowired
	private RequestDao requestDao;
	
	@Autowired
	private UserDao userDao;

	@Autowired
	private Mapper dozerMapper;

	@RequestMapping(method = RequestMethod.GET, value = "{id}")
	public @ResponseBody RequestDto find(@PathVariable Long userId, @PathVariable Long id) {
		try {
			// TODO Vérifier que les ID de la demande sont cohérents
			return dozerMapper.map(requestDao.get(id), RequestDto.class);
		} catch (ObjectRetrievalFailureException e) {
			throw new NotFoundException();
		} catch (Exception e) {
			throw new InternalServerErrorException();
		}
	}

	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody List<RequestDto> findAll(@PathVariable Long userId) {
		try {
			Set<Request> requests = userDao.get(userId).getRequests();
			List<RequestDto> requestDtos = new ArrayList<RequestDto>(requests.size());
			for (Request request : requests) {
				requestDtos.add(dozerMapper.map(request, RequestDto.class));
			}
			return requestDtos;
		} catch (Exception e) {
			throw new InternalServerErrorException();
		}
	}

	@RequestMapping(method = RequestMethod.POST)
	@ResponseStatus(HttpStatus.CREATED)
	public void save(@PathVariable Long userId, @RequestBody RequestDto requestDto) {
		// TODO lancer une BadRequestException si problème client, Spring lance des UnrecognizedPropertyException mais impossible de les chopper
		// TODO Empecher l'attribution de l'id de la requete
		// TODO Renvoyer le Response header location avec l'URI de la nouvelle requete créée
		try {
			Request request = dozerMapper.map(requestDto, Request.class);
			request.setUser(userDao.get(userId));
			requestDao.save(request);
		} catch (ObjectRetrievalFailureException e) {
			throw new NotFoundException();
		} catch (Exception e) {
			throw new InternalServerErrorException();
		}
	}

	@RequestMapping(method = RequestMethod.PUT, value = "{id}")
	@ResponseStatus(HttpStatus.OK)
	public void update(@PathVariable Long id, @RequestBody RequestDto requestDto) {
		// TODO lancer une BadRequestException si problème client, Spring lance des UnrecognizedPropertyException mais impossible de les chopper
		// TODO Vérifier que l'id est cohérent avec la requete
		try {
			Request request = requestDao.get(id);
			dozerMapper.map(requestDto, request);
			requestDao.save(request);
		} catch (ObjectRetrievalFailureException e) {
			throw new NotFoundException();
		} catch (Exception e) {
			throw new InternalServerErrorException();
		}
	}

	@RequestMapping(method = RequestMethod.DELETE, value = "{id}")
	@ResponseStatus(HttpStatus.OK)
	public void delete(@PathVariable Long id) {
		try {
			requestDao.remove(id);
		} catch (ObjectRetrievalFailureException e) {
			throw new NotFoundException();
		} catch (Exception e) {
			throw new InternalServerErrorException();
		}
	}

}
